//
// ********************************************************************
// * License and Disclaimer                                           *
// *                                                                  *
// * The  Geant4 software  is  copyright of the Copyright Holders  of *
// * the Geant4 Collaboration.  It is provided  under  the terms  and *
// * conditions of the Geant4 Software License,  included in the file *
// * LICENSE and available at  http://cern.ch/geant4/license .  These *
// * include a list of copyright holders.                             *
// *                                                                  *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work  make  any representation or  warranty, express or implied, *
// * regarding  this  software system or assume any liability for its *
// * use.  Please see the license in the file  LICENSE  and URL above *
// * for the full disclaimer and the limitation of liability.         *
// *                                                                  *
// * This  code  implementation is the result of  the  scientific and *
// * technical work of the GEANT4 collaboration.                      *
// * By using,  copying,  modifying or  distributing the software (or *
// * any work based  on the software)  you  agree  to acknowledge its *
// * use  in  resulting  scientific  publications,  and indicate your *
// * acceptance of all terms of the Geant4 Software license.          *
// ********************************************************************
//
//
// --------------------------------------------------------------
//   GEANT 4 - Underground Dark Matter Detector Advanced Example
//
//      For information related to this code contact: Alex Howard
//      e-mail: alexander.howard@cern.ch
// --------------------------------------------------------------
// Comments
//
//                  Underground Advanced
//               by A. Howard and H. Araujo 
//                    (27th November 2001)
//
// DetectorConstruction header
// --------------------------------------------------------------

#ifndef DMXDetectorConstruction_h
#define DMXDetectorConstruction_h 1

#include "G4VUserDetectorConstruction.hh"
#include "globals.hh"

class G4LogicalVolume;
class G4VPhysicalVolume;
class G4Material;
class G4MaterialPropertiesTable;
class G4UserLimits;
class DMXScintSD;
class DMXPmtSD;
class DMXDetectorMessenger;

//static const G4double c = 299792458.* m / s;
//static const G4double h = 6.62606957e-34*joule*s;   
// static const G4double LambdaE = 2.0 * 3.14159265358979323846 * 1.973269602e-16 * m * GeV; //c*h
// static const G4double k = 1.380658e-23 * joule/kelvin; // the Boltzmann constant
// static const G4double dyne = 1.e-5 * newton; // compressibility uses this CGS unit

// static const G4double GArRho  = 1.784 * kg/m3; // GAr (gas) mass density
// static const G4double LArRho = 1.390 * g/cm3; // LAr (liquid) mass density 

// const G4double nanometer = 1e-9;
// const G4double micrometer = 1e-6;
// const G4double km = 1e3;
// const G4double cm2 = 1e-4;
// const G4double cm3 = 1e-6;
// const G4double m3 = 1.;
// const G4double g = 1e-3;
// const G4double kg = 1.;
// const G4double newton = 1.;
const G4double dyne = 1e-5 * newton;
const G4double k = 1.380658e-23 * joule/kelvin; // the Boltzmann constant

const G4double c = 299792458.;
const G4double h = 4.135667516e-15;
const G4double LambdaE = c*h;
//const G4double k = 1.380658e-23; 

const G4double lowLambda = 115.0;
const G4double highLambda = 598.0;

//Properties of the Ar (GAr gas and LAr liquid)
const G4double GArRho  = 1.784 * kg/m3; // GAr (gas) mass density
const G4double LArRho = 1.390 * g/cm3; // LAr (liquid) mass density
const G4double LArKT = 2.18e-10 * cm2/dyne; // LAr isothermal compressibility
const G4double temperature = 87.8; // -185.35 deg 

class DMXDetectorConstruction : public G4VUserDetectorConstruction 
{
public:

  DMXDetectorConstruction();
  ~DMXDetectorConstruction();

public:

  G4VPhysicalVolume* Construct();

  void SetArMaterialTable();
  void SetRoomEnergyCut(G4double);
  void SetEnergyCut(G4double);
  void SetTimeCut(G4double);
  void SetRoomTimeCut(G4double);
  //  void UpdateGeometry();

  G4double GetArScintillationSpectrum(G4double);
  G4double GetLArEpsilon(G4double);
  G4double GetLArRefIndex(G4double);
  G4double GetLArRayLength(G4double,G4double);
  G4double GetLArAbsLength(G4double);

private:

  void DefineMaterials();

  //  G4MaterialPropertiesTable *LAr_mt;
  //G4MaterialPropertiesTable *GAr_mt;

  G4UserLimits*    theUserLimitsForRoom; 
  G4UserLimits*    theUserLimitsForWorld; 
  G4UserLimits*    theUserLimitsForDetector; 
  //  G4UserLimits*    theUserLimitsForXenon; 

  G4double         theMaxTimeCuts;
  G4double         theMaxStepSize;
  G4double         theDetectorStepSize;
  G4double         theWorldStepSize;
  G4double         theMinEkine;
  G4double         theRoomMinEkine;
  
  G4double         theRoomTimeCut;


#include "DMXDetectorMaterial.ihh"  // materials used

  G4double worldRadius;                // sizes
  G4double worldHeight;
  G4double sourceZ;
  G4double sourceZ2;


  G4LogicalVolume*   world_log;        // pointers
  G4VPhysicalVolume* world_phys;  

#include "DMXDetectorRoom.ihh"

  G4LogicalVolume*   lLab;
  G4VPhysicalVolume* pLab;

  G4LogicalVolume*   lJC;
  G4VPhysicalVolume* pJC;

  //****Fiducial****//

  G4LogicalVolume*   lHGAr;
  G4VPhysicalVolume* pHGAr;

  G4LogicalVolume*   lLAr;
  G4VPhysicalVolume* pLAr;

  G4LogicalVolume*   lUBLAr;
  G4VPhysicalVolume* pULAr;
  G4VPhysicalVolume* pBLAr;

  G4LogicalVolume*   lMLAr;
  G4VPhysicalVolume* pMLAr;

  G4LogicalVolume*   lGAr;
  G4VPhysicalVolume* pGAr;

  G4LogicalVolume*   lFid;
  G4VPhysicalVolume* pFid;

  G4LogicalVolume*   lJFid;
  G4VPhysicalVolume* pJFid;

  G4LogicalVolume*   lMFid;
  G4VPhysicalVolume* pMFid;

  //****collimeter****//

  G4LogicalVolume*   lPb;
  G4VPhysicalVolume* pPb1;  
  G4VPhysicalVolume* pPb2;  

  G4LogicalVolume*   lcolimeter;
  G4VPhysicalVolume* pcolimeter;  

  //****WLS TEST****//

  G4LogicalVolume*   lTPBBox;
  G4VPhysicalVolume* pTPBBox;  

  G4LogicalVolume*   lWindow;
  G4VPhysicalVolume* pWindow;  

  G4LogicalVolume*   lBoxRef;
  G4VPhysicalVolume* pBoxRef;  

  G4LogicalVolume*   lSTP;
  G4VPhysicalVolume* pSTP1;  
  G4VPhysicalVolume* pSTP2;  
  G4VPhysicalVolume* pSTP3;  
  G4VPhysicalVolume* pSTP4;  

  //****RunV****//

  G4LogicalVolume*   lCylinder;
  G4VPhysicalVolume* pCylinder;

  G4LogicalVolume*   lReflector;
  G4VPhysicalVolume* pReflector;

  G4LogicalVolume*   lrefwls;
  G4VPhysicalVolume* prefwls;

  G4LogicalVolume*   lrefakewls;
  G4VPhysicalVolume* prefakewls;

  G4LogicalVolume*   lstr1;
  G4LogicalVolume*   lstr2;
  G4VPhysicalVolume* pstr1;
  G4VPhysicalVolume* pstr2;
  G4VPhysicalVolume* pstr11;
  G4VPhysicalVolume* pstr22;

  G4LogicalVolume*   lPwls;
  G4VPhysicalVolume* pPwls1;
  G4VPhysicalVolume* pPwls2;

  G4LogicalVolume*   lHPMTw;
  G4VPhysicalVolume* pHPMTw1;
  G4VPhysicalVolume* pHPMTw2;

  G4LogicalVolume*   lHPMT1;
  G4LogicalVolume*   lHPMT2;
  G4VPhysicalVolume* pHPMT1;
  G4VPhysicalVolume* pHPMT2;

  G4LogicalVolume*   lJPwls;
  G4VPhysicalVolume* pJPwls1;
  G4VPhysicalVolume* pJPwls2;
  G4VPhysicalVolume* pJPwls3;
  G4VPhysicalVolume* pJPwls4;
  G4VPhysicalVolume* pJPwls5;
  G4VPhysicalVolume* pJPwls6;

  G4LogicalVolume*   lJPMTw;
  G4VPhysicalVolume* pJPMTw1;
  G4VPhysicalVolume* pJPMTw2;
  G4VPhysicalVolume* pJPMTw3;
  G4VPhysicalVolume* pJPMTw4;
  G4VPhysicalVolume* pJPMTw5;
  G4VPhysicalVolume* pJPMTw6;

  G4LogicalVolume*   lJPMT1;
  G4LogicalVolume*   lJPMT2;
  G4VPhysicalVolume* pJPMT1;
  G4VPhysicalVolume* pJPMT2;
  G4VPhysicalVolume* pJPMT3;
  G4VPhysicalVolume* pJPMT4;
  G4VPhysicalVolume* pJPMT5;
  G4VPhysicalVolume* pJPMT6;

  //  G4LogicalVolume*   lMPwls;
  G4LogicalVolume*   lMPwls1;
  G4LogicalVolume*   lMPwls2;
  G4VPhysicalVolume* pMPwls1;
  G4VPhysicalVolume* pMPwls2;

  G4LogicalVolume*   lMPMTw;
  G4VPhysicalVolume* pMPMTw1;
  G4VPhysicalVolume* pMPMTw2;

  G4LogicalVolume*   lMPMT;
  G4VPhysicalVolume* pMPMT1;
  G4VPhysicalVolume* pMPMT2;

  //---------------Reflector---------------//

  G4LogicalVolume*   lJReflectorS;
  G4VPhysicalVolume* pJReflectorS;

  G4LogicalVolume*   lJrefwlsS;
  G4VPhysicalVolume* pJrefwlsS;

  G4LogicalVolume*   lMReflector;
  G4VPhysicalVolume* pMReflector;

  G4LogicalVolume*   lMrefwls;
  G4VPhysicalVolume* pMrefwls;

  G4LogicalVolume*   lJReflectorT;
  G4VPhysicalVolume* pJReflectorTt;
  G4VPhysicalVolume* pJReflectorTb;

  G4LogicalVolume*   lJrefwlsT;
  G4VPhysicalVolume* pJrefwlsTt;
  G4VPhysicalVolume* pJrefwlsTb;

  G4LogicalVolume*   loutrefwls;
  G4VPhysicalVolume* poutrefwls;

  G4LogicalVolume*   lmoutrefwls;
  G4VPhysicalVolume* pmoutrefwls;

  G4LogicalVolume*   lmoutref;
  G4VPhysicalVolume* pmoutref;

  //---------------JPMT---------------//

  G4LogicalVolume*   lJPMTCylinder;
  G4VPhysicalVolume* pJPMTCylinder1;
  G4VPhysicalVolume* pJPMTCylinder2;
  G4VPhysicalVolume* pJPMTCylinder3;
  G4VPhysicalVolume* pJPMTCylinder4;
  G4VPhysicalVolume* pJPMTCylinder5;
  G4VPhysicalVolume* pJPMTCylinder6;

  //---------------MEG---------------//

  G4LogicalVolume*   lMPMTCylinder;
  G4VPhysicalVolume* pMPMTCylinder1;
  G4VPhysicalVolume* pMPMTCylinder2;

  //------------VETO PMT---------------//

  G4LogicalVolume*   lvetowls;
  G4VPhysicalVolume* pvetowls1;
  G4VPhysicalVolume* pvetowls2;
  G4VPhysicalVolume* pvetowls3;
  G4VPhysicalVolume* pvetowls4;
  G4VPhysicalVolume* pvetowls5;
  G4VPhysicalVolume* pvetowls6;
  G4VPhysicalVolume* pvetowls7;
  G4VPhysicalVolume* pvetowls8;

  G4LogicalVolume*   lvetoPMTw;
  G4VPhysicalVolume* pvetoPMTw1;
  G4VPhysicalVolume* pvetoPMTw2;
  G4VPhysicalVolume* pvetoPMTw3;
  G4VPhysicalVolume* pvetoPMTw4;
  G4VPhysicalVolume* pvetoPMTw5;
  G4VPhysicalVolume* pvetoPMTw6;
  G4VPhysicalVolume* pvetoPMTw7;
  G4VPhysicalVolume* pvetoPMTw8;

  G4LogicalVolume*   lvetoPMT;
  G4VPhysicalVolume* pvetoPMT1;
  G4VPhysicalVolume* pvetoPMT2;
  G4VPhysicalVolume* pvetoPMT3;
  G4VPhysicalVolume* pvetoPMT4;
  G4VPhysicalVolume* pvetoPMT5;
  G4VPhysicalVolume* pvetoPMT6;
  G4VPhysicalVolume* pvetoPMT7;
  G4VPhysicalVolume* pvetoPMT8;

  G4LogicalVolume*   lvetoCylinder;
  G4VPhysicalVolume*  pvetoCylinder1;
  G4VPhysicalVolume*  pvetoCylinder2;
  G4VPhysicalVolume*  pvetoCylinder3;
  G4VPhysicalVolume*  pvetoCylinder4;
  G4VPhysicalVolume*  pvetoCylinder5;
  G4VPhysicalVolume*  pvetoCylinder6;
  G4VPhysicalVolume*  pvetoCylinder7;
  G4VPhysicalVolume*  pvetoCylinder8;

  G4LogicalVolume*   lvetofixplate;
  G4VPhysicalVolume*  pvetofixplate1;
  G4VPhysicalVolume*  pvetofixplate2;

  //****Alpha Run && Gas TEST****//

  G4LogicalVolume*   lcol;
  G4VPhysicalVolume* pcol;

  G4LogicalVolume*   lpul;
  G4VPhysicalVolume* ppul;
  G4VPhysicalVolume* ppul2;

  G4LogicalVolume*   lcap;
  G4VPhysicalVolume* pcap;

  G4LogicalVolume*   lESR;
  G4VPhysicalVolume* pESR;

  G4LogicalVolume*   lLap;
  G4VPhysicalVolume* pLap;

  G4LogicalVolume*   lParaloid;
  G4VPhysicalVolume* pParaloid;

  G4LogicalVolume*   lpult;
  G4VPhysicalVolume* ppult;

  G4LogicalVolume*   lAm241;
  G4VPhysicalVolume* pAm241;

  G4LogicalVolume*   lpulw;
  G4VPhysicalVolume* ppulw;

  G4LogicalVolume*   lNaI;
  G4VPhysicalVolume* pNaI;

  //****Acryl TEST****//

  G4LogicalVolume*   lAcryl;
  G4VPhysicalVolume* pAcryl1;
  G4VPhysicalVolume* pAcryl2;

  DMXScintSD*  LXeSD;            //pointer to sensitive detectors
  DMXPmtSD* pmtSD;

  // pointer to the Detector Messenger:
  DMXDetectorMessenger*  detectorMessenger;

};

#endif

